/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.oron3.bouncer.genericgl;

import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;

import javax.microedition.khronos.opengles.GL;
import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.opengles.GL10Ext;
import javax.microedition.khronos.opengles.GL11;
import javax.microedition.khronos.opengles.GL11Ext;

import android.util.Log;

/**
 * Allows retrieving the current matrix even if the current OpenGL ES
 * driver does not support retrieving the current matrix.
 *
 * Note: the actual matrix may differ from the retrieved matrix, due
 * to differences in the way the math is implemented by GLMatrixWrapper
 * as compared to the way the math is implemented by the OpenGL ES
 * driver.
 */
public class MatrixTrackingGL implements GL, GL10, GL10Ext, GL11, GL11Ext {
	private final GL10 mgl;
	private GL10Ext mgl10Ext;
	private GL11 mgl11;
	private GL11Ext mgl11Ext;
	private int mMatrixMode;
	private MatrixStack mCurrent;
	private final MatrixStack mModelView;
	private final MatrixStack mTexture;
	private final MatrixStack mProjection;

	private final static boolean _check = false;
	ByteBuffer mByteBuffer;
	FloatBuffer mFloatBuffer;
	float[] mCheckA;
	float[] mCheckB;

	public MatrixTrackingGL(final GL gl) {
		mgl = (GL10) gl;
		if (gl instanceof GL10Ext) {
			mgl10Ext = (GL10Ext) gl;
		}
		if (gl instanceof GL11) {
			mgl11 = (GL11) gl;
		}
		if (gl instanceof GL11Ext) {
			mgl11Ext = (GL11Ext) gl;
		}
		mModelView = new MatrixStack();
		mProjection = new MatrixStack();
		mTexture = new MatrixStack();
		mCurrent = mModelView;
		mMatrixMode = GL10.GL_MODELVIEW;
	}

	// ---------------------------------------------------------------------
	// GL10 methods:

		@Override
		public void glActiveTexture(final int texture) {
			mgl.glActiveTexture(texture);
		}

		@Override
		public void glAlphaFunc(final int func, final float ref) {
			mgl.glAlphaFunc(func, ref);
		}

		@Override
		public void glAlphaFuncx(final int func, final int ref) {
			mgl.glAlphaFuncx(func, ref);
		}

		@Override
		public void glBindTexture(final int target, final int texture) {
			mgl.glBindTexture(target, texture);
		}

		@Override
		public void glBlendFunc(final int sfactor, final int dfactor) {
			mgl.glBlendFunc(sfactor, dfactor);
		}

		@Override
		public void glClear(final int mask) {
			mgl.glClear(mask);
		}

		@Override
		public void glClearColor(final float red, final float green, final float blue, final float alpha) {
			mgl.glClearColor(red, green, blue, alpha);
		}

		@Override
		public void glClearColorx(final int red, final int green, final int blue, final int alpha) {
			mgl.glClearColorx(red, green, blue, alpha);
		}

		@Override
		public void glClearDepthf(final float depth) {
			mgl.glClearDepthf(depth);
		}

		@Override
		public void glClearDepthx(final int depth) {
			mgl.glClearDepthx(depth);
		}

		@Override
		public void glClearStencil(final int s) {
			mgl.glClearStencil(s);
		}

		@Override
		public void glClientActiveTexture(final int texture) {
			mgl.glClientActiveTexture(texture);
		}

		@Override
		public void glColor4f(final float red, final float green, final float blue, final float alpha) {
			mgl.glColor4f(red, green, blue, alpha);
		}

		@Override
		public void glColor4x(final int red, final int green, final int blue, final int alpha) {
			mgl.glColor4x(red, green, blue, alpha);
		}

		@Override
		public void glColorMask(final boolean red, final boolean green, final boolean blue,
				final boolean alpha) {
			mgl.glColorMask(red, green, blue, alpha);
		}

		@Override
		public void glColorPointer(final int size, final int type, final int stride, final Buffer pointer) {
			mgl.glColorPointer(size, type, stride, pointer);
		}

		@Override
		public void glCompressedTexImage2D(final int target, final int level,
				final int internalformat, final int width, final int height, final int border,
				final int imageSize, final Buffer data) {
			mgl.glCompressedTexImage2D(target, level, internalformat, width,
					height, border, imageSize, data);
		}

		@Override
		public void glCompressedTexSubImage2D(final int target, final int level, final int xoffset,
				final int yoffset, final int width, final int height, final int format, final int imageSize,
				final Buffer data) {
			mgl.glCompressedTexSubImage2D(target, level, xoffset, yoffset, width,
					height, format, imageSize, data);
		}

		@Override
		public void glCopyTexImage2D(final int target, final int level, final int internalformat,
				final int x, final int y, final int width, final int height, final int border) {
			mgl.glCopyTexImage2D(target, level, internalformat, x, y, width,
					height, border);
		}

		@Override
		public void glCopyTexSubImage2D(final int target, final int level, final int xoffset,
				final int yoffset, final int x, final int y, final int width, final int height) {
			mgl.glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width,
					height);
		}

		@Override
		public void glCullFace(final int mode) {
			mgl.glCullFace(mode);
		}

		@Override
		public void glDeleteTextures(final int n, final int[] textures, final int offset) {
			mgl.glDeleteTextures(n, textures, offset);
		}

		@Override
		public void glDeleteTextures(final int n, final IntBuffer textures) {
			mgl.glDeleteTextures(n, textures);
		}

		@Override
		public void glDepthFunc(final int func) {
			mgl.glDepthFunc(func);
		}

		@Override
		public void glDepthMask(final boolean flag) {
			mgl.glDepthMask(flag);
		}

		@Override
		public void glDepthRangef(final float near, final float far) {
			mgl.glDepthRangef(near, far);
		}

		@Override
		public void glDepthRangex(final int near, final int far) {
			mgl.glDepthRangex(near, far);
		}

		@Override
		public void glDisable(final int cap) {
			mgl.glDisable(cap);
		}

		@Override
		public void glDisableClientState(final int array) {
			mgl.glDisableClientState(array);
		}

		@Override
		public void glDrawArrays(final int mode, final int first, final int count) {
			mgl.glDrawArrays(mode, first, count);
		}

		@Override
		public void glDrawElements(final int mode, final int count, final int type, final Buffer indices) {
			mgl.glDrawElements(mode, count, type, indices);
		}

		@Override
		public void glEnable(final int cap) {
			mgl.glEnable(cap);
		}

		@Override
		public void glEnableClientState(final int array) {
			mgl.glEnableClientState(array);
		}

		@Override
		public void glFinish() {
			mgl.glFinish();
		}

		@Override
		public void glFlush() {
			mgl.glFlush();
		}

		@Override
		public void glFogf(final int pname, final float param) {
			mgl.glFogf(pname, param);
		}

		@Override
		public void glFogfv(final int pname, final float[] params, final int offset) {
			mgl.glFogfv(pname, params, offset);
		}

		@Override
		public void glFogfv(final int pname, final FloatBuffer params) {
			mgl.glFogfv(pname, params);
		}

		@Override
		public void glFogx(final int pname, final int param) {
			mgl.glFogx(pname, param);
		}

		@Override
		public void glFogxv(final int pname, final int[] params, final int offset) {
			mgl.glFogxv(pname, params, offset);
		}

		@Override
		public void glFogxv(final int pname, final IntBuffer params) {
			mgl.glFogxv(pname, params);
		}

		@Override
		public void glFrontFace(final int mode) {
			mgl.glFrontFace(mode);
		}

		@Override
		public void glFrustumf(final float left, final float right, final float bottom, final float top,
				final float near, final float far) {
			mCurrent.glFrustumf(left, right, bottom, top, near, far);
			mgl.glFrustumf(left, right, bottom, top, near, far);
			if ( _check) check();
		}

		@Override
		public void glFrustumx(final int left, final int right, final int bottom, final int top, final int near,
				final int far) {
			mCurrent.glFrustumx(left, right, bottom, top, near, far);
			mgl.glFrustumx(left, right, bottom, top, near, far);
			if ( _check) check();
		}

		@Override
		public void glGenTextures(final int n, final int[] textures, final int offset) {
			mgl.glGenTextures(n, textures, offset);
		}

		@Override
		public void glGenTextures(final int n, final IntBuffer textures) {
			mgl.glGenTextures(n, textures);
		}

		@Override
		public int glGetError() {
			final int result = mgl.glGetError();
			return result;
		}

		@Override
		public void glGetIntegerv(final int pname, final int[] params, final int offset) {
			mgl.glGetIntegerv(pname, params, offset);
		}

		@Override
		public void glGetIntegerv(final int pname, final IntBuffer params) {
			mgl.glGetIntegerv(pname, params);
		}

		@Override
		public String glGetString(final int name) {
			final String result = mgl.glGetString(name);
			return result;
		}

		@Override
		public void glHint(final int target, final int mode) {
			mgl.glHint(target, mode);
		}

		@Override
		public void glLightModelf(final int pname, final float param) {
			mgl.glLightModelf(pname, param);
		}

		@Override
		public void glLightModelfv(final int pname, final float[] params, final int offset) {
			mgl.glLightModelfv(pname, params, offset);
		}

		@Override
		public void glLightModelfv(final int pname, final FloatBuffer params) {
			mgl.glLightModelfv(pname, params);
		}

		@Override
		public void glLightModelx(final int pname, final int param) {
			mgl.glLightModelx(pname, param);
		}

		@Override
		public void glLightModelxv(final int pname, final int[] params, final int offset) {
			mgl.glLightModelxv(pname, params, offset);
		}

		@Override
		public void glLightModelxv(final int pname, final IntBuffer params) {
			mgl.glLightModelxv(pname, params);
		}

		@Override
		public void glLightf(final int light, final int pname, final float param) {
			mgl.glLightf(light, pname, param);
		}

		@Override
		public void glLightfv(final int light, final int pname, final float[] params, final int offset) {
			mgl.glLightfv(light, pname, params, offset);
		}

		@Override
		public void glLightfv(final int light, final int pname, final FloatBuffer params) {
			mgl.glLightfv(light, pname, params);
		}

		@Override
		public void glLightx(final int light, final int pname, final int param) {
			mgl.glLightx(light, pname, param);
		}

		@Override
		public void glLightxv(final int light, final int pname, final int[] params, final int offset) {
			mgl.glLightxv(light, pname, params, offset);
		}

		@Override
		public void glLightxv(final int light, final int pname, final IntBuffer params) {
			mgl.glLightxv(light, pname, params);
		}

		@Override
		public void glLineWidth(final float width) {
			mgl.glLineWidth(width);
		}

		@Override
		public void glLineWidthx(final int width) {
			mgl.glLineWidthx(width);
		}

		@Override
		public void glLoadIdentity() {
			mCurrent.glLoadIdentity();
			mgl.glLoadIdentity();
			if ( _check) check();
		}

		@Override
		public void glLoadMatrixf(final float[] m, final int offset) {
			mCurrent.glLoadMatrixf(m, offset);
			mgl.glLoadMatrixf(m, offset);
			if ( _check) check();
		}

		@Override
		public void glLoadMatrixf(final FloatBuffer m) {
			final int position = m.position();
			mCurrent.glLoadMatrixf(m);
			m.position(position);
			mgl.glLoadMatrixf(m);
			if ( _check) check();
		}

		@Override
		public void glLoadMatrixx(final int[] m, final int offset) {
			mCurrent.glLoadMatrixx(m, offset);
			mgl.glLoadMatrixx(m, offset);
			if ( _check) check();
		}

		@Override
		public void glLoadMatrixx(final IntBuffer m) {
			final int position = m.position();
			mCurrent.glLoadMatrixx(m);
			m.position(position);
			mgl.glLoadMatrixx(m);
			if ( _check) check();
		}

		@Override
		public void glLogicOp(final int opcode) {
			mgl.glLogicOp(opcode);
		}

		@Override
		public void glMaterialf(final int face, final int pname, final float param) {
			mgl.glMaterialf(face, pname, param);
		}

		@Override
		public void glMaterialfv(final int face, final int pname, final float[] params, final int offset) {
			mgl.glMaterialfv(face, pname, params, offset);
		}

		@Override
		public void glMaterialfv(final int face, final int pname, final FloatBuffer params) {
			mgl.glMaterialfv(face, pname, params);
		}

		@Override
		public void glMaterialx(final int face, final int pname, final int param) {
			mgl.glMaterialx(face, pname, param);
		}

		@Override
		public void glMaterialxv(final int face, final int pname, final int[] params, final int offset) {
			mgl.glMaterialxv(face, pname, params, offset);
		}

		@Override
		public void glMaterialxv(final int face, final int pname, final IntBuffer params) {
			mgl.glMaterialxv(face, pname, params);
		}

		@Override
		public void glMatrixMode(final int mode) {
			switch (mode) {
			case GL10.GL_MODELVIEW:
				mCurrent = mModelView;
				break;
			case GL10.GL_TEXTURE:
				mCurrent = mTexture;
				break;
			case GL10.GL_PROJECTION:
				mCurrent = mProjection;
				break;
			default:
				throw new IllegalArgumentException("Unknown matrix mode: " + mode);
			}
			mgl.glMatrixMode(mode);
			mMatrixMode = mode;
			if ( _check) check();
		}

		@Override
		public void glMultMatrixf(final float[] m, final int offset) {
			mCurrent.glMultMatrixf(m, offset);
			mgl.glMultMatrixf(m, offset);
			if ( _check) check();
		}

		@Override
		public void glMultMatrixf(final FloatBuffer m) {
			final int position = m.position();
			mCurrent.glMultMatrixf(m);
			m.position(position);
			mgl.glMultMatrixf(m);
			if ( _check) check();
		}

		@Override
		public void glMultMatrixx(final int[] m, final int offset) {
			mCurrent.glMultMatrixx(m, offset);
			mgl.glMultMatrixx(m, offset);
			if ( _check) check();
		}

		@Override
		public void glMultMatrixx(final IntBuffer m) {
			final int position = m.position();
			mCurrent.glMultMatrixx(m);
			m.position(position);
			mgl.glMultMatrixx(m);
			if ( _check) check();
		}

		@Override
		public void glMultiTexCoord4f(final int target,
				final float s, final float t, final float r, final float q) {
			mgl.glMultiTexCoord4f(target, s, t, r, q);
		}

		@Override
		public void glMultiTexCoord4x(final int target, final int s, final int t, final int r, final int q) {
			mgl.glMultiTexCoord4x(target, s, t, r, q);
		}

		@Override
		public void glNormal3f(final float nx, final float ny, final float nz) {
			mgl.glNormal3f(nx, ny, nz);
		}

		@Override
		public void glNormal3x(final int nx, final int ny, final int nz) {
			mgl.glNormal3x(nx, ny, nz);
		}

		@Override
		public void glNormalPointer(final int type, final int stride, final Buffer pointer) {
			mgl.glNormalPointer(type, stride, pointer);
		}

		@Override
		public void glOrthof(final float left, final float right, final float bottom, final float top,
				final float near, final float far) {
			mCurrent.glOrthof(left, right, bottom, top, near, far);
			mgl.glOrthof(left, right, bottom, top, near, far);
			if ( _check) check();
		}

		@Override
		public void glOrthox(final int left, final int right, final int bottom, final int top, final int near,
				final int far) {
			mCurrent.glOrthox(left, right, bottom, top, near, far);
			mgl.glOrthox(left, right, bottom, top, near, far);
			if ( _check) check();
		}

		@Override
		public void glPixelStorei(final int pname, final int param) {
			mgl.glPixelStorei(pname, param);
		}

		@Override
		public void glPointSize(final float size) {
			mgl.glPointSize(size);
		}

		@Override
		public void glPointSizex(final int size) {
			mgl.glPointSizex(size);
		}

		@Override
		public void glPolygonOffset(final float factor, final float units) {
			mgl.glPolygonOffset(factor, units);
		}

		@Override
		public void glPolygonOffsetx(final int factor, final int units) {
			mgl.glPolygonOffsetx(factor, units);
		}

		@Override
		public void glPopMatrix() {
			mCurrent.glPopMatrix();
			mgl.glPopMatrix();
			if ( _check) check();
		}

		@Override
		public void glPushMatrix() {
			mCurrent.glPushMatrix();
			mgl.glPushMatrix();
			if ( _check) check();
		}

		@Override
		public void glReadPixels(final int x, final int y, final int width, final int height, final int format,
				final int type, final Buffer pixels) {
			mgl.glReadPixels(x, y, width, height, format, type, pixels);
		}

		@Override
		public void glRotatef(final float angle, final float x, final float y, final float z) {
			mCurrent.glRotatef(angle, x, y, z);
			mgl.glRotatef(angle, x, y, z);
			if ( _check) check();
		}

		@Override
		public void glRotatex(final int angle, final int x, final int y, final int z) {
			mCurrent.glRotatex(angle, x, y, z);
			mgl.glRotatex(angle, x, y, z);
			if ( _check) check();
		}

		@Override
		public void glSampleCoverage(final float value, final boolean invert) {
			mgl.glSampleCoverage(value, invert);
		}

		@Override
		public void glSampleCoveragex(final int value, final boolean invert) {
			mgl.glSampleCoveragex(value, invert);
		}

		@Override
		public void glScalef(final float x, final float y, final float z) {
			mCurrent.glScalef(x, y, z);
			mgl.glScalef(x, y, z);
			if ( _check) check();
		}

		@Override
		public void glScalex(final int x, final int y, final int z) {
			mCurrent.glScalex(x, y, z);
			mgl.glScalex(x, y, z);
			if ( _check) check();
		}

		@Override
		public void glScissor(final int x, final int y, final int width, final int height) {
			mgl.glScissor(x, y, width, height);
		}

		@Override
		public void glShadeModel(final int mode) {
			mgl.glShadeModel(mode);
		}

		@Override
		public void glStencilFunc(final int func, final int ref, final int mask) {
			mgl.glStencilFunc(func, ref, mask);
		}

		@Override
		public void glStencilMask(final int mask) {
			mgl.glStencilMask(mask);
		}

		@Override
		public void glStencilOp(final int fail, final int zfail, final int zpass) {
			mgl.glStencilOp(fail, zfail, zpass);
		}

		@Override
		public void glTexCoordPointer(final int size, final int type,
				final int stride, final Buffer pointer) {
			mgl.glTexCoordPointer(size, type, stride, pointer);
		}

		@Override
		public void glTexEnvf(final int target, final int pname, final float param) {
			mgl.glTexEnvf(target, pname, param);
		}

		@Override
		public void glTexEnvfv(final int target, final int pname, final float[] params, final int offset) {
			mgl.glTexEnvfv(target, pname, params, offset);
		}

		@Override
		public void glTexEnvfv(final int target, final int pname, final FloatBuffer params) {
			mgl.glTexEnvfv(target, pname, params);
		}

		@Override
		public void glTexEnvx(final int target, final int pname, final int param) {
			mgl.glTexEnvx(target, pname, param);
		}

		@Override
		public void glTexEnvxv(final int target, final int pname, final int[] params, final int offset) {
			mgl.glTexEnvxv(target, pname, params, offset);
		}

		@Override
		public void glTexEnvxv(final int target, final int pname, final IntBuffer params) {
			mgl.glTexEnvxv(target, pname, params);
		}

		@Override
		public void glTexImage2D(final int target, final int level, final int internalformat,
				final int width, final int height, final int border, final int format, final int type,
				final Buffer pixels) {
			mgl.glTexImage2D(target, level, internalformat, width, height, border,
					format, type, pixels);
		}

		@Override
		public void glTexParameterf(final int target, final int pname, final float param) {
			mgl.glTexParameterf(target, pname, param);
		}

		@Override
		public void glTexParameterx(final int target, final int pname, final int param) {
			mgl.glTexParameterx(target, pname, param);
		}

		@Override
		public void glTexParameteriv(final int target, final int pname, final int[] params, final int offset) {
			mgl11.glTexParameteriv(target, pname, params, offset);
		}

		@Override
		public void glTexParameteriv(final int target, final int pname, final IntBuffer params) {
			mgl11.glTexParameteriv(target, pname, params);
		}

		@Override
		public void glTexSubImage2D(final int target, final int level, final int xoffset,
				final int yoffset, final int width, final int height, final int format, final int type,
				final Buffer pixels) {
			mgl.glTexSubImage2D(target, level, xoffset, yoffset, width, height,
					format, type, pixels);
		}

		@Override
		public void glTranslatef(final float x, final float y, final float z) {
			mCurrent.glTranslatef(x, y, z);
			mgl.glTranslatef(x, y, z);
			if ( _check) check();
		}

		@Override
		public void glTranslatex(final int x, final int y, final int z) {
			mCurrent.glTranslatex(x, y, z);
			mgl.glTranslatex(x, y, z);
			if ( _check) check();
		}

		@Override
		public void glVertexPointer(final int size, final int type,
				final int stride, final Buffer pointer) {
			mgl.glVertexPointer(size, type, stride, pointer);
		}

		@Override
		public void glViewport(final int x, final int y, final int width, final int height) {
			mgl.glViewport(x, y, width, height);
		}

		@Override
		public void glClipPlanef(final int plane, final float[] equation, final int offset) {
			mgl11.glClipPlanef(plane, equation, offset);
		}

		@Override
		public void glClipPlanef(final int plane, final FloatBuffer equation) {
			mgl11.glClipPlanef(plane, equation);
		}

		@Override
		public void glClipPlanex(final int plane, final int[] equation, final int offset) {
			mgl11.glClipPlanex(plane, equation, offset);
		}

		@Override
		public void glClipPlanex(final int plane, final IntBuffer equation) {
			mgl11.glClipPlanex(plane, equation);
		}

		// Draw Texture Extension

		@Override
		public void glDrawTexfOES(final float x, final float y, final float z,
				final float width, final float height) {
			mgl11Ext.glDrawTexfOES(x, y, z, width, height);
		}

		@Override
		public void glDrawTexfvOES(final float[] coords, final int offset) {
			mgl11Ext.glDrawTexfvOES(coords, offset);
		}

		@Override
		public void glDrawTexfvOES(final FloatBuffer coords) {
			mgl11Ext.glDrawTexfvOES(coords);
		}

		@Override
		public void glDrawTexiOES(final int x, final int y, final int z, final int width, final int height) {
			mgl11Ext.glDrawTexiOES(x, y, z, width, height);
		}

		@Override
		public void glDrawTexivOES(final int[] coords, final int offset) {
			mgl11Ext.glDrawTexivOES(coords, offset);
		}

		@Override
		public void glDrawTexivOES(final IntBuffer coords) {
			mgl11Ext.glDrawTexivOES(coords);
		}

		@Override
		public void glDrawTexsOES(final short x, final short y, final short z,
				final short width, final short height) {
			mgl11Ext.glDrawTexsOES(x, y, z, width, height);
		}

		@Override
		public void glDrawTexsvOES(final short[] coords, final int offset) {
			mgl11Ext.glDrawTexsvOES(coords, offset);
		}

		@Override
		public void glDrawTexsvOES(final ShortBuffer coords) {
			mgl11Ext.glDrawTexsvOES(coords);
		}

		@Override
		public void glDrawTexxOES(final int x, final int y, final int z, final int width, final int height) {
			mgl11Ext.glDrawTexxOES(x, y, z, width, height);
		}

		@Override
		public void glDrawTexxvOES(final int[] coords, final int offset) {
			mgl11Ext.glDrawTexxvOES(coords, offset);
		}

		@Override
		public void glDrawTexxvOES(final IntBuffer coords) {
			mgl11Ext.glDrawTexxvOES(coords);
		}

		@Override
		public int glQueryMatrixxOES(final int[] mantissa, final int mantissaOffset,
				final int[] exponent, final int exponentOffset) {
			return mgl10Ext.glQueryMatrixxOES(mantissa, mantissaOffset,
					exponent, exponentOffset);
		}

		@Override
		public int glQueryMatrixxOES(final IntBuffer mantissa, final IntBuffer exponent) {
			return mgl10Ext.glQueryMatrixxOES(mantissa, exponent);
		}

		// Unsupported GL11 methods

		@Override
		public void glBindBuffer(final int target, final int buffer) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glBufferData(final int target, final int size, final Buffer data, final int usage) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glBufferSubData(final int target, final int offset, final int size, final Buffer data) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glColor4ub(final byte red, final byte green, final byte blue, final byte alpha) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glDeleteBuffers(final int n, final int[] buffers, final int offset) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glDeleteBuffers(final int n, final IntBuffer buffers) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glGenBuffers(final int n, final int[] buffers, final int offset) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glGenBuffers(final int n, final IntBuffer buffers) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glGetBooleanv(final int pname, final boolean[] params, final int offset) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glGetBooleanv(final int pname, final IntBuffer params) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glGetBufferParameteriv(final int target, final int pname, final int[] params, final int offset) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glGetBufferParameteriv(final int target, final int pname, final IntBuffer params) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glGetClipPlanef(final int pname, final float[] eqn, final int offset) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glGetClipPlanef(final int pname, final FloatBuffer eqn) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glGetClipPlanex(final int pname, final int[] eqn, final int offset) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glGetClipPlanex(final int pname, final IntBuffer eqn) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glGetFixedv(final int pname, final int[] params, final int offset) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glGetFixedv(final int pname, final IntBuffer params) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glGetFloatv(final int pname, final float[] params, final int offset) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glGetFloatv(final int pname, final FloatBuffer params) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glGetLightfv(final int light, final int pname, final float[] params, final int offset) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glGetLightfv(final int light, final int pname, final FloatBuffer params) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glGetLightxv(final int light, final int pname, final int[] params, final int offset) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glGetLightxv(final int light, final int pname, final IntBuffer params) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glGetMaterialfv(final int face, final int pname, final float[] params, final int offset) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glGetMaterialfv(final int face, final int pname, final FloatBuffer params) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glGetMaterialxv(final int face, final int pname, final int[] params, final int offset) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glGetMaterialxv(final int face, final int pname, final IntBuffer params) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glGetTexEnviv(final int env, final int pname, final int[] params, final int offset) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glGetTexEnviv(final int env, final int pname, final IntBuffer params) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glGetTexEnvxv(final int env, final int pname, final int[] params, final int offset) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glGetTexEnvxv(final int env, final int pname, final IntBuffer params) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glGetTexParameterfv(final int target, final int pname, final float[] params, final int offset) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glGetTexParameterfv(final int target, final int pname, final FloatBuffer params) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glGetTexParameteriv(final int target, final int pname, final int[] params, final int offset) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glGetTexParameteriv(final int target, final int pname, final IntBuffer params) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glGetTexParameterxv(final int target, final int pname, final int[] params, final int offset) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glGetTexParameterxv(final int target, final int pname, final IntBuffer params) {
			throw new UnsupportedOperationException();
		}

		@Override
		public boolean glIsBuffer(final int buffer) {
			throw new UnsupportedOperationException();
		}

		@Override
		public boolean glIsEnabled(final int cap) {
			throw new UnsupportedOperationException();
		}

		@Override
		public boolean glIsTexture(final int texture) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glPointParameterf(final int pname, final float param) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glPointParameterfv(final int pname, final float[] params, final int offset) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glPointParameterfv(final int pname, final FloatBuffer params) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glPointParameterx(final int pname, final int param) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glPointParameterxv(final int pname, final int[] params, final int offset) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glPointParameterxv(final int pname, final IntBuffer params) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glPointSizePointerOES(final int type, final int stride, final Buffer pointer) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glTexEnvi(final int target, final int pname, final int param) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glTexEnviv(final int target, final int pname, final int[] params, final int offset) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glTexEnviv(final int target, final int pname, final IntBuffer params) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glTexParameterfv(final int target, final int pname, final float[] params, final int offset) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glTexParameterfv(final int target, final int pname, final FloatBuffer params) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glTexParameteri(final int target, final int pname, final int param) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glTexParameterxv(final int target, final int pname, final int[] params, final int offset) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glTexParameterxv(final int target, final int pname, final IntBuffer params) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glColorPointer(final int size, final int type, final int stride, final int offset) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glDrawElements(final int mode, final int count, final int type, final int offset) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glGetPointerv(final int pname, final Buffer[] params) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glNormalPointer(final int type, final int stride, final int offset) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glTexCoordPointer(final int size, final int type, final int stride, final int offset) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glVertexPointer(final int size, final int type, final int stride, final int offset) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glCurrentPaletteMatrixOES(final int matrixpaletteindex) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glLoadPaletteFromModelViewMatrixOES() {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glMatrixIndexPointerOES(final int size, final int type, final int stride,
				final Buffer pointer) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glMatrixIndexPointerOES(final int size, final int type, final int stride,
				final int offset) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glWeightPointerOES(final int size, final int type, final int stride,
				final Buffer pointer) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void glWeightPointerOES(final int size, final int type, final int stride, final int offset) {
			throw new UnsupportedOperationException();
		}

		/**
		 * Get the current matrix
		 */

		 public void getMatrix(final float[] m, final int offset) {
			mCurrent.getMatrix(m, offset);
		}

		/**
		 * Get the current matrix mode
		 */

		 public int getMatrixMode() {
			return mMatrixMode;
		}

		private void check() {
			int oesMode;
			switch (mMatrixMode) {
			case GL_MODELVIEW:
				oesMode = GL11.GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES;
				break;
			case GL_PROJECTION:
				oesMode = GL11.GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES;
				break;
			case GL_TEXTURE:
				oesMode = GL11.GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES;
				break;
			default:
				throw new IllegalArgumentException("Unknown matrix mode");
			}

			if ( mByteBuffer == null) {
				mCheckA = new float[16];
				mCheckB = new float[16];
				mByteBuffer = ByteBuffer.allocateDirect(64);
				mByteBuffer.order(ByteOrder.nativeOrder());
				mFloatBuffer = mByteBuffer.asFloatBuffer();
			}
			mgl.glGetIntegerv(oesMode, mByteBuffer.asIntBuffer());
			for(int i = 0; i < 16; i++) {
				mCheckB[i] = mFloatBuffer.get(i);
			}
			mCurrent.getMatrix(mCheckA, 0);

			boolean fail = false;
			for(int i = 0; i < 16; i++) {
				if (mCheckA[i] != mCheckB[i]) {
					Log.d("GLMatWrap", "i:" + i + " a:" + mCheckA[i]
							+ " a:" + mCheckB[i]);
					fail = true;
				}
			}
			if (fail) {
				throw new IllegalArgumentException("Matrix math difference.");
			}
		}

}
